#include <iostream>
#include <thread>

// void Print(int num) {
//     std::cout << std::this_thread::get_id() << std::endl;
//     for (int i = 0; i < num; i++)
//         std::cout << i << " ";
//     std::cout << "\n";
// }

// int main() {
//     // std::thread t1(Print, 100);

//     // t1.join();

//     std::thread t1;
//     std::cout << t1.get_id() << std::endl;

//     return 0;

//     return 0;
// }


// void ThreadFunc(int a) {
//     std::cout << "thread1: " << a << std::endl;
// }

// class TF {
// public:
//     void operator()() {
//         std::cout << "thread3" << std::endl;    
//     }
// };

// int main() {
//     std::thread t1(ThreadFunc, 10);
//     std::thread t2([](){std::cout << "thread2" << std::endl;});
//     TF tf;
//     std::thread t3(tf);

//     t1.join();
//     t2.join();
//     t3.join();
//     return 0;
// }
#include <mutex>

// void AddNum(int n, int& x, std::mutex& mtx) {
//     mtx.lock();
//     for (int i = 0; i < n; i++)
//         x++;
//     mtx.unlock();
// }

// void AddNum(int n, int* x, std::mutex* mtx) {
//     mtx->lock();
//     for (int i = 0; i < n; i++)
//         (*x)++;
//     mtx->unlock();
// }

// int main() {
//     std::mutex mtx;
//     int x = 0;
//     // std::thread t1(AddNum, 1000, std::ref(x), std::ref(mtx));
//     // std::thread t2(AddNum, 2000, std::ref(x), std::ref(mtx));
//     std::thread t1(AddNum, 1000, &x, &mtx);
//     std::thread t2(AddNum, 2000, &x, &mtx);
    
//     t1.join();
//     t2.join();

//     std::cout << x << std::endl;
//     return 0;
// }
#include <vector>

// int main() {
//     std::vector<std::thread> vthds;
//     int num = 5;
//     vthds.resize(num);

//     int x = 0;
//     std::mutex mtx;

//     auto func = [&](int n) {
//         mtx.lock();
//         // 可能在执行循环的时候异常退出
//         for (int i = 0; i < n; i++) {
//             ++x;
//         }
//         mtx.unlock();
//     };

//     // 使用移动拷贝赋值
//     for (auto& thd : vthds)
//         thd = std::thread(func, 1000);
    
//     for (auto& thd : vthds)
//         thd.join();

//     std::cout << x << std::endl;
//     return 0;
// }


// int main() {
//     std::vector<std::thread> vthds;
//     int num = 5;
//     vthds.resize(num);

//     int x = 0;
//     std::mutex mtx;

//     auto func = [&](int n) {
//         // mtx.lock();
//         LockGuard lockguard(mtx);
//         // 可能在执行循环的时候异常退出
//         for (int i = 0; i < n; i++) {
//             ++x;
//         }
//         // mtx.unlock();
//     };

//     // 使用移动拷贝赋值
//     for (auto& thd : vthds)
//         thd = std::thread(func, 1000);
    
//     for (auto& thd : vthds)
//         thd.join();

//     std::cout << x << std::endl;
//     return 0;
// }

class LockGuard {
public:
    LockGuard(std::mutex& mtx)
        : _mtx(mtx)
    {
        _mtx.lock();
    }

    ~LockGuard() {
        _mtx.unlock();
    }
private:
    std::mutex& _mtx;
};

#include <atomic>

int main() {
    std::vector<std::thread> vthds;
    int num = 5;
    vthds.resize(num);

    std::atomic<int> x {0};
    auto func = [&](int n) {
        for (int i = 0; i < n; i++) {
            x.fetch_add(3);
        }
    };

    for (auto& thd : vthds)
        thd = std::thread(func, 1000);
    
    for (auto& thd : vthds)
        thd.join();    

    // atomic重载了<<运算符
    std::cout << x << std::endl;
    // 适用load函数获取x内的值
    printf("%d\n", x.load());
    return 0;
}